﻿using FluentAssertions;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using NewRetail.Application.Components.Goods;
using NewRetail.Application.Components.Goods.Entity;
using NewRetail.Application.Components.Warehouse.Entity;
using NewRetail.Application.Core;
using NewRetail.Application.Core.SingleStore;
using System;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Uow;

namespace NewRetail.Api.Controllers
{
    //商品退货周期 add by cl 20230322
    [NewRetailRoute("goods-return-cycle")]
    public class GoodsReturnCycleController : BaseController<GoodsCategoryReturnCycle, GoodsReturnCyclePagingDto>
    {
        private readonly IGoodsReturnCycleService goodsReturnCycleService;
        private readonly ISingleStoreService singleStoreService;

        public GoodsReturnCycleController(IGoodsReturnCycleService goodsReturnCycleService, ISingleStoreService singleStoreService)
        {
            this.goodsReturnCycleService = goodsReturnCycleService;
            this.singleStoreService = singleStoreService;
        }

        public override async Task<ResponseEntity<GoodsCategoryReturnCycle[]>> QueryAll()
        {
            var data = await base.QueryAll();
            data.ThrowIfNotSuccess();
            data.Data ??= Array.Empty<GoodsCategoryReturnCycle>();

            data.Data = await this.goodsReturnCycleService.AttachGoodsCategory(data.Data);
            data.Data = await this.goodsReturnCycleService.AttachSupplier(data.Data);

            return data;
        }

        protected override async Task<IQueryable<GoodsCategoryReturnCycle>> FilterQueryPaging(DbContext db, IQueryable<GoodsCategoryReturnCycle> query, GoodsReturnCyclePagingDto dto)
        {
            if (!string.IsNullOrWhiteSpace(dto.categoryId))
            {
                query = query.Where(x => x.categoryId == dto.categoryId);
            }

            query = query.WhereIf(!string.IsNullOrWhiteSpace(dto.supplierId), x => x.supplierId == dto.supplierId);

            //单店权限
            string roleWarehouseId = this.singleStoreService.CurrentStore;
            if (!string.IsNullOrWhiteSpace(roleWarehouseId))
            {
                var goodCategoryIds = db.Set<GoodsCategory>().Where(x => x.warehouseID == roleWarehouseId).Select(x => x.Id);
                query = query.Where(x => goodCategoryIds.Contains(x.categoryId));
            }

            await Task.CompletedTask;
            return query;
        }

        public override async Task<ResponseEntity<PagedResultDto<GoodsCategoryReturnCycle>>> QueryPaging([FromBody] GoodsReturnCyclePagingDto dto)
        {
            var res = await base.QueryPaging(dto);

            if (res.Data?.Items?.Any() ?? false)
            {
                res.Data.Items = await this.goodsReturnCycleService.AttachSupplier(res.Data.Items.ToArray());
                res.Data.Items = await this.goodsReturnCycleService.AttachGoodsCategory(res.Data.Items.ToArray());
            }

            return res;
        }

        [HttpPost("save-multiple")]
        public async Task<ResponseEntity<GoodsCategoryReturnCycle[]>> SaveMultiple([FromBody] GoodsCategoryReturnCycle[] data)
        {
            data.Should().NotBeNullOrEmpty();
            using var uow = this.UnitOfWorkManager.Begin(requiresNew: true, isTransactional: true);
            try
            {
                var db = await this.Repo.GetDbContextAsync();
                var goodsReturnCycleSet = db.Set<GoodsCategoryReturnCycle>();

                foreach (var m in data)
                {
                    if (string.IsNullOrWhiteSpace(m.Id))
                    {
                        await this.BeforeInsertDataInitial(m);
                        this.EntityHelper.InitEntity(m);
                        await this.BeforeInsert(m);
                        goodsReturnCycleSet.Add(m);
                    }
                    else
                    {
                        var entity = await goodsReturnCycleSet.FirstOrDefaultAsync(x => x.Id == m.Id);
                        if (entity == null)
                        {
                            throw new UserFriendlyException("更新的对象不存在");
                        }
                        await this.BeforeUpdate(entity, m);
                        this.EntityHelper.SetUpdationInfo(entity);
                    }
                }

                await db.SaveChangesAsync();

                await uow.CompleteAsync();
                return new ResponseEntity<GoodsCategoryReturnCycle[]>().SetData(data);
            }
            catch
            {
                await uow.RollbackAsync();
                throw;
            }
        }
    }
}
